package com.framework.service.impl;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.framework.dto.PageRequestDTO;
import com.framework.dto.UpdateUserDTO;
import com.framework.entity.*;
import com.framework.repository.MergeFileRepository;
import com.framework.repository.RoleRepository;
import com.framework.repository.UserRoleRepository;
import com.framework.service.MergeFileService;
import com.framework.service.RoleMenuService;
import com.framework.service.UserRoleService;
import com.framework.vo.MergeFileVO;
import com.framework.vo.UserInfoVO;
import com.framework.repository.UserRepository;
import com.framework.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @Description: 用户服务接口实现
 * @Author: JamesYao
 * @DateTime: 2023/12/14 16:06
 */

@Service
@RequiredArgsConstructor
@Transactional
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    private final UserRoleRepository userRoleRepository;

    private final RoleRepository roleRepository;

    private final UserRoleService userRoleService;

    private final RoleMenuService roleMenuService;

    private final MergeFileRepository mergeFileRepository;


    /**
     * 获取所有用户
     *
     * @return SaResult
     */
    @Override
    public SaResult getAllUser(PageRequestDTO pageRequestDTO) {
        SaSession session = StpUtil.getSession();
        UUID userId = (UUID) session.get("userId");
        List<Role> rolesByUserId = userRoleService.findRolesByUserId(userId);
        if (rolesByUserId.isEmpty()) {
            return SaResult.error("当前登录用户无角色");
        }
        String name = rolesByUserId.get(0).getName();
        if (!name.equals("管理员")) {
            return SaResult.error("当前登录用户无查询权限");
        }
        PageRequest pageable = PageRequest.of(pageRequestDTO.getPage(), pageRequestDTO.getSize());
        Page<User> all = userRepository.findAll(pageable);

        ArrayList<Object> results = new ArrayList<>();
        for (User user : all) {
            UpdateUserDTO updateUserDTO = new UpdateUserDTO();
            BeanUtils.copyProperties(user, updateUserDTO);
            List<Role> roles = userRoleService.findRolesByUserId(user.getId());
            if (!roles.isEmpty()) {
                updateUserDTO.setRoleName(roles.get(0).getName());
            }
            results.add(updateUserDTO);
        }
        Page<Object> pageResult = new PageImpl<>(results, pageable, all.getTotalElements());
        return SaResult.data(pageResult);
    }

    /**
     * 根据账户和密码获取账户ID
     *
     * @param account 账户
     * @param ps      密码
     * @return UUID 账户ID
     */
    @Override
    public UUID getAccountId(String account, String ps) {
        User byAccountAndPs = userRepository.findByAccountAndPs(account, ps);
        if (Objects.isNull(byAccountAndPs)) {
            SaResult.error("账号或密码错误");
        }
        return byAccountAndPs.getId();
    }

    /**
     * 保存用户信息
     *
     * @param userDTO 用户信息
     * @return SaResult 保存结果
     */
    @Override
    public SaResult saveUser(UpdateUserDTO userDTO) {
        User byAccount = userRepository.findByAccount
                (userDTO.getAccount());
        if (byAccount != null) {
            return SaResult.error("当前账号已存在");
        }
        Role role = roleRepository.findByName(userDTO.getRoleName());
        if (Objects.isNull(role)) {
            return SaResult.error("当前角色不存在");
        }
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        userRepository.save(user);
        UserRole userRole = new UserRole();
        userRole.setRoleId(role.getId());
        userRole.setUserId(user.getId());
        userRoleService.saveUserRole(userRole);
        return SaResult.ok("注册成功");
    }

    /**
     * 根据用户ID获取用户信息
     *
     * @return User 用户信息
     */
    @Override
    public SaResult getUserInfo() {
        SaSession session = StpUtil.getSession();
        UUID userId = (UUID) session.get("userId");
        if (Objects.isNull(userId)) {
            return SaResult.error("用户ID有误");
        }
        UserInfoVO userInfoDTO = new UserInfoVO();
        List<Role> rolesByUserId = userRoleService.findRolesByUserId(userId);
        for (Role role : rolesByUserId) {
            List<Menu> menusByRoleId = roleMenuService.findMenusByRoleId(role.getId());
            userInfoDTO.setMenus(menusByRoleId);
        }
        User user = userRepository.getReferenceById(userId);

        userInfoDTO.setName(user.getName());
        List<Role> rolesByUserId1 = userRoleService.findRolesByUserId(userId);
        userInfoDTO.setAccountTypeName(rolesByUserId1.get(0).getName());
        userInfoDTO.setTel(user.getTel());

        List<MergeFile> mergeFiles = mergeFileRepository.findByUserId(userId);
        long l = 0L;
        for (MergeFile mergeFile : mergeFiles) {
            Long size = mergeFile.getSize();
            if (Objects.nonNull(size)) {
                l += size;
            }
        }
        l = l / (1024 * 1024);
        userInfoDTO.setMemorySpace(l);

        return SaResult.data(userInfoDTO);
    }

    /**
     * 删除用户
     *
     * @param userId 用户ID
     * @return 删除结果
     */
    @Override
    public SaResult deleteUser(UUID userId) {
        // 查询所有符合条件的用户
        User user = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("未查询到用户相关信息"));
        if (Objects.isNull(user)) {
            return SaResult.error("当前用户不存在");
        }
        List<User> all = userRepository.findAll();
        if (all.size() <= 1) {
            return SaResult.error("当前用户为最后一位用户，无法删除");
        }
        // 删除用户与角色的关联关系
        userRoleRepository.deleteAllByUserId(userId);
        // 删除用户与文件的关联关系
        mergeFileRepository.deleteByUserId(userId);
        // 删除用户
        userRepository.deleteById(userId);
        return SaResult.ok("删除成功");
    }

    /**
     * 更新用户信息
     *
     * @param userDTO 用户信息DTO
     * @return 更新结果
     */
    @Override
    public SaResult updateUser(UpdateUserDTO userDTO) {
        // 根据用户ID查询用户信息，若不存在则抛出异常
        User user1 = userRepository.findById(userDTO.getId()).orElseThrow(() -> new RuntimeException("未查询到用户相关信息"));
        if (Objects.isNull(user1)) {
            return SaResult.error("当前用户不存在");
        }

        // 判断角色名是否与当前用户的角色名相同
        boolean equals = userDTO.getRoleName().equals(user1.getName());
        if (!equals) {
            // 根据角色名查询角色信息
            Role byName = roleRepository.findByName(userDTO.getRoleName());
            UUID roleId = byName.getId();
            // 更新用户的角色信息
            userRoleRepository.updateRoleByUserId(roleId, userDTO.getId());
        }

        // 更新用户信息
        user1.setAccount(userDTO.getAccount());
        user1.setName(userDTO.getName());
        user1.setTel(userDTO.getTel());

        // 保存更新后的用户信息
        userRepository.save(user1);

        return SaResult.ok("更新成功");
    }


}